package com.softserveinc.moviedbapp.parser;

import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;

import com.softserveinc.moviedbapp.model.Movie;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class SAXParserMovieBrowse implements IMovieDBMethodBrowseSearch {

	private static final String TAG = SAXParserMovieBrowse.class.getSimpleName();

	/* names of the XML tags */
	static final String NAME = "name";
	static final String ID = "id";
	static final String RELEASE_DATE = "released";
	static final String RATING = "rating";
	static final String CERTIFICATION = "certification";
	static final String VOTES = "votes";
	static final String MOVIES = "movies";
	static final String MOVIE = "movie";
	static final String IMAGES = "images";
	static final String POSTER = "image";

	private int retryCount = 5;

	private InputStream is;

	public SAXParserMovieBrowse(final InputStream is) {
		this.is = is;
	}

	/* performs actual parsing */
	@Override
	public List<Movie> parse() {
		Log.d(TAG, "entered parse()");
		final Movie currentMovie = new Movie();
		final List<Movie> movies = new ArrayList<Movie>();

		/* sets the root tag of the xml */
		RootElement rootTag = new RootElement("OpenSearchDescription");
		Element moviesTag = rootTag.getChild(MOVIES);
		Element movieTag = moviesTag.requireChild(MOVIE);

		/* when encounter the movie tag, create a new movie and add a listener */
		movieTag.setEndElementListener(new EndElementListener() {
			@Override
			public void end() {
				movies.add(currentMovie.copy());
			}
		});

		/* set the contents of the name tag */
		movieTag.getChild(NAME).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovie.setName(body);
			}
		});

		/* get the contents of the id tag */
		movieTag.getChild(ID).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovie.setMovieId(Integer.parseInt(body));
			}
		});

		/* get the contents of the votes tag */
		movieTag.getChild(VOTES).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovie.setVotes(Integer.parseInt(body));
			}
		});

		/* get the contents of the rating tag */
		movieTag.getChild(RATING).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovie.setRating(Double.parseDouble(body));
			}
		});

		/* get the contents of the certification tag */
		movieTag.getChild(CERTIFICATION).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				if (body == null) {
					currentMovie.setCertification("NR");
				} else {
					currentMovie.setCertification(body);
				}
			}
		});

		/* get the contents of the released tag */
		movieTag.getChild(RELEASE_DATE).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(final String body) {
				currentMovie.setReleased(body);
			}
		});

		/* get inside the images tag and get the contents of the image tag */
		Element imagesTag = movieTag.getChild(IMAGES);
		imagesTag.getChild(POSTER).setStartElementListener(new StartElementListener() {

			@Override
			public void start(final Attributes attributes) {
				;

				/* choose the right image url (poster type and thumb size) */
				if (attributes.getValue(0).equals("poster") && attributes.getValue(2).equals("thumb")) {
					currentMovie.setThumbPosterUrl(attributes.getValue("url"));
				}
			}
		});

		/*for debug purposes only*/
		rootTag.setEndElementListener(new EndElementListener() {

			@Override
			public void end() {
				Log.d(TAG, "parser </OpenSearchDescription> ");

			}
		});

		/* start parsing */
		/* try for 5 times to load image */
		while (retryCount > 0) {
			try {
				Log.d(TAG, "STARTED PARSING movie list with ANDROID SAX");
				Xml.parse(is, Xml.Encoding.UTF_8, rootTag.getContentHandler());
				Log.d(TAG, "\nSUCCESSFULLY COMPLETED PARSING movie list with ANDROID SAX");
			} catch (IOException e) {
				Log.e(TAG, "Parsing MOVIE.BROWSE XML FAILED." + retryCount + " attemps left", e);
				retryCount--;
				continue;

			} catch (SAXException e) {
				Log.e(TAG, "SAXException ", e);
				Movie movie = new Movie();
				movie.setName("Nothing found.");
				movie.setCertification("NR");
				movies.add(movie);

				break;

			}
			break;
		}
		return movies;

	}
}
